home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource4 / 234_01 / ctlr.c < prev    next >
Text File  |  1987-06-18  |  23KB  |  872 lines

  1. /*
  2.   HEADER: CUG     nnn.nn;
  3.   TITLE:     XDIR - Hard Disk Manager
  4.   VERSION:     1.0 for IBM-PC
  5.   DATE:      Apr 03, 1987
  6.   DESCRIPTION:     Hard Disk Manager for IBM PC
  7.   KEYWORDS:     Hard Disk Manager Dump Directory
  8.   SYSTEM:     IBM-PC and Compatiables
  9.   FILENAME:      ctlr.C
  10.   WARNINGS:     None
  11.   CRC:         N/A
  12.   SEE-ALSO:     HDIR.DOC and XDIR.DOC
  13.   AUTHOR:     Mike Blakley 15645 SW 82 Cir Ln #76, Miami, Fl 33193
  14.   COMPILERS:     ECO-C
  15.   REFERENCES:     XDIR.DOC
  16. */
  17.  
  18.  
  19. /*
  20.    ctlr
  21.    display main menu screen for word search
  22.    process request
  23. */
  24. #include "stdio.h"
  25. #include "dos.h"
  26. #include "dir.h"
  27. /*
  28.     xscr.h
  29.     header file for scan function of XDIR
  30.  
  31. */
  32. /*  xscan functions */
  33.  
  34. int xscan(char *fnam, char string[10][80],int ans[],char *options);
  35. int sbuff(char *buff,char *string, int max, char *options);
  36. int strxcmp(char *buff1, char *buff2, int maxlen, char *options);
  37. int strxchr(char *buff, char c, int max);
  38.  
  39. /* xword functions */
  40. void xword(char *buffer,char words[10][80]);
  41.  
  42. /* xscr functions */
  43. int ctlr(char *fnam);
  44. int xscr(char *fnam, char *xnam, char *stext,
  45.          int *sflag, int *stype, char *ext, char *opts);
  46. int getitem(int *item, int row, int col, char *text, int len);
  47. void sepname(char *all, char *path, char *file);
  48. void cline(int row, int col, int len);
  49.  
  50. /* sdir functions */
  51.  
  52. int sdir(char *buff, char *filename, int action, char ext[10][80],int type);
  53. int cmpext(char *fnam, char *ext);
  54.  
  55. /*********** end of header definition *************************/
  56.  
  57. /*
  58. main()
  59. {
  60.       ctlr("\\bin\\xdir.exe");
  61.  
  62. }
  63. */
  64. /*
  65.    ctlr
  66.    controller module
  67.  
  68. */
  69. ctlr(fnam)
  70. char *fnam;
  71. {
  72.      int  i,j, k, sflag, stype;
  73.      char xnam[80], stext[80], extents[80];
  74.      int  ans[10];               /* answer for search */
  75.      char words[10][80];         /* words to search */
  76.      char filename[20];          /* work area for file name */
  77.      char extnames[10][80];      /* extent names */
  78.      char options[80];           /* search options */
  79.      struct {
  80.        char snam[40];            /* search file name */
  81.        int  sopts[10];           /* search hits */
  82.        } sfiles[100];            /* store max of 100 files */
  83.      int scount;
  84.  
  85.      i = xscr(fnam,xnam,stext,&sflag,&stype,extents,options);
  86.  
  87.  
  88.      if (i == -1)
  89.         {writestr("\nSearch aborted ");
  90.         return(-1);
  91.         }
  92.  
  93.      cursor(2,50);
  94.      writestr("Begin search ... ");
  95.      cursor(5,10);
  96.      writestr("SEARCHING ");
  97.      cursor(7,10);
  98.      writestr("Located ");
  99.      scount = 0;
  100.  
  101.      for (i=0;i<10;i++) words[i][0] = 0;   /* init */
  102.      xword(stext,words);          /* xlate search text to words */
  103.  
  104.      if (stype == 0)       /* search a single file */
  105.         {
  106.         i = xscan(xnam,words,ans,options);
  107.         if (i != 1)
  108.             {
  109.             writestr("\nXscan failure ");
  110.             getch();
  111.             exit(0);          /* scan failure */
  112.             }
  113.         for (i=j=0;i<10;i++)
  114.            if (ans[i] == 1) ++j;      /* determine any hits */
  115.  
  116.         if (j)
  117.            {
  118.            writestr("\nSearch words found in file ");
  119.            writestr(xnam);
  120.            for (i=0;i<10;i++)
  121.              if (ans[i]==1) {putchar('\n');writestr(words[i]);}
  122.            }
  123.         else
  124.            {
  125.            writestr("\nNo match found in file ");
  126.            writestr(xnam);
  127.            }
  128.          }    /* end if stype  = 0 */
  129.  
  130.        else                    /* search a directory */
  131.         {
  132.            for (i=0;i<10;i++) extnames[i][0] = 0;   /* init */
  133.            xword(extents,extnames);          /* xlate search extents to words */
  134.  
  135.           i = sdir(xnam,filename,1,extnames,sflag);   /* open the directory */
  136.           while (i = sdir(xnam,filename,0,extnames,sflag))
  137.            {
  138.            cursor(5,23);
  139.            for (i=0;i<20;i++) putchar(' ');
  140.            cursor(5,23);
  141.            writestr(filename);
  142.            j = xscan(filename,words,ans,options);   /* search the file */
  143.            if (j != 1)
  144.               {
  145.               writestr("\nXscan failure");
  146.               getch();
  147.               exit(0);
  148.               }
  149.  
  150.            for (i=j=0;i<10;i++) if (ans[i] == 1) ++j;      /* determine any hits */
  151.  
  152.            if (j)
  153.              {
  154.              cursor(7,23);
  155.              for (i=0;i<20;i++) putchar(' ');
  156.              cursor(7,23);
  157.              if (scount < 100)
  158.                 {
  159.                 strcpy(sfiles[scount].snam,filename);
  160.                 for (i=0;i<10;i++) sfiles[scount].sopts[i] = ans[i];
  161.                 ++scount;
  162.                 }
  163.              for (i=0;i<10;i++)
  164.                if (ans[i]==1) {putchar(' ');writestr(words[i]);}
  165.              }
  166.           }        /* end while */
  167.          }    /* end if stype  != 0 */
  168.  
  169.         /*************** print out the results of search *************/
  170.         clrscr();
  171.         writestr("\nResults of search located text as follows: ");
  172.         for (i=k=0;((i<10)&&(words[i][0] != 0));i++) ++k;
  173.  
  174.         for (i=0;i<scount;i++)
  175.         {
  176.         writestr("\nFile ");
  177.         writestr(sfiles[i].snam);
  178.         for (j=0;j<k;j++)
  179.            if (sfiles[i].sopts[j] == 1) {putchar(' ');writestr(words[j]);}
  180.         }  /* end of dump loop */
  181.         writestr("\nPress any key to continue ");   /* pause screen */
  182.         getch();
  183.  
  184. }
  185.  
  186. /*
  187.    xscan
  188.    scan a file for text strings
  189.    to be included with xdir upon completion of module
  190.  
  191. */
  192. #define BUFFSIZE 8000
  193.  
  194. int  xscan(fnam,string,ans,options)
  195. char *fnam;
  196. char string[10][80]; /* search strings */
  197. int  ans[];          /* search results */
  198. char *options;       /* search options */
  199. {
  200.      int  fd, flen,i,j,k,l,m;
  201.      char *alloc(int amt);
  202.      char *buff;
  203.      /* char temp[20]; */
  204.  
  205.      fd = open(fnam,0);
  206.      if (fd == EOF)
  207.         {
  208.         writestr("\nCan't open file ");
  209.         writestr(fnam);
  210.         return(-1);
  211.         }
  212.  
  213.      buff = alloc(BUFFSIZE+1);
  214.      if (buff == NULL) return (-1);
  215.  
  216.      for (i=0;string[i][0] != 0;i++) ans[i] = 0;  /* init to false */
  217.      k = i;           /* count of search strings */
  218.  
  219.      flen = BUFFSIZE;
  220.  
  221.      while (flen == BUFFSIZE)
  222.      {
  223.        for (j=l=0;l<k;l++) j += ans[l];   /* determine if search s/b ended
  224.                                           because all strings located */
  225.        if (j == k) break;                 /* yes, all found */
  226.        flen = read(fd,buff,BUFFSIZE);
  227.  
  228.        for (i=0;string[i][0] != 0;i++)
  229.        {
  230.        if (ans[i] == 0)    /* only test where no match yet */
  231.           {
  232.           m = xcomp(buff,string[i],options,flen);   /* search buffer */
  233.           if (m == 0) ans[i] = 1;     /* record answer */
  234.           }
  235.        }
  236.      }
  237.  
  238.      free(buff);           /* free the buffer */
  239.      close(fd);            /* close the file */
  240.      return (1);
  241. }
  242.  
  243.  
  244. /*
  245.     xword
  246.     parse a string into words
  247.  
  248. */
  249.  
  250. void xword(buffer,words)
  251. char *buffer;   /* buffer to parse */
  252. char words[10][80];
  253. {
  254.  
  255.       int  i, j, state;
  256.       char *cp, *cpo;
  257.       int  c;
  258.       int  num;            /* used in octal numbers */
  259.       char temp[80];
  260.       int  tflag;          /* flag - current words in tic marks */
  261.  
  262.       for (i=0;i<10;i++) words[i][0] = 0;
  263.  
  264.       state = i = j = tflag = 0;
  265.       cp = buffer;
  266.       cpo = temp;
  267.  
  268.       while (1)
  269.       {
  270.       c = (int) *cp++;      /* get a character */
  271.  
  272.  
  273.           switch (state)
  274.           {
  275.           case 0:           /* begin a new word */
  276.             tflag = 0;
  277.             cpo = temp;
  278.             if (c == 0) state = 98;
  279.             else if (c == ' ') state = 0;     /* skip leading spaces */
  280.             else if (c == '\'') {tflag = 1;state = 1;}
  281.             else {*cpo++ = c;state = 1;}
  282.             break;
  283.  
  284.           case 1:           /* start a new word tick mark */
  285.             if (c == '\\') state = 2;
  286.             else if ((c == '\'') && tflag)
  287.                 {*cpo = 0;state = 0;strcpy(words[i++],temp);}
  288.             else if ((c == ' ') && (tflag == 0))
  289.                 {*cpo = 0;state = 0;strcpy(words[i++],temp);}
  290.  
  291.             else if (c == 0) state=98;
  292.  
  293.             else {*cpo++ = c;state = 1;}
  294.             break;
  295.  
  296.           case 2:
  297.             num = 0;     /* set octal constant to zero, if any */
  298.             if (c == 0) state=98;
  299.             else
  300.             if (c == 'n') {*cpo++ = '\n';state =1;}
  301.             else
  302.             if (c == 'b') {*cpo++ = '\b';state =1;}
  303.             else
  304.             if (c == '\''){*cpo++ = '\'';state = 1;}
  305.             else
  306.             if (c == '\\') {*cpo++ = '\\';state = 1;}
  307.             else
  308.             if (c == 'r') {*cpo++ = '\r';state =1;}
  309.             else
  310.             if (c == 'f') {*cpo++ = '\f';state =1;}
  311.             else
  312.             if (c == '\"'){*cpo++ = '\"';state = 1;}
  313.             else
  314.             if ((c >= '0') && (c <= '7')) {num = c - '0';state = 5;}
  315.             else          {*cpo++ = c; state=1;}
  316.             break;
  317.  
  318.  
  319.           case 5:        /* octal constant */
  320.             if (c == 0) {*cpo++ = num; state = 98;}
  321.             else
  322.             if ((c >= '0') && (c <= '7'))
  323.                {
  324.                num *= 8;
  325.                num += c - '0';
  326.                state = 6;
  327.                }
  328.             else {*cpo++ = num;*cpo++=c;state = 1;}
  329.             break;
  330.  
  331.          case 6:        /* octal constant */
  332.             if (c == 0) {*cpo++ = num; state = 98;}
  333.             else
  334.             if ((c >= '0') && (c <= '7'))
  335.                {
  336.                num *= 8;
  337.                num += c - '0';
  338.                *cpo++ = num;
  339.                state = 1;
  340.                }
  341.             else {*cpo++ = num;*cpo++=c;state = 1;}
  342.             break;
  343.  
  344.           case 98:      /* exit point */
  345.             *cpo = 0;
  346.             strcpy(words[i],temp);
  347.             state = 99;
  348.             break;
  349.           }             /* end case */
  350.  
  351.         if (state == 99) break;
  352.  
  353.       }              /* end while */
  354.  
  355.  
  356. }            /* end subroutine */
  357.  
  358. /*
  359.    xscr
  360.    display main menu screen for word search
  361.    process request
  362. */
  363.  
  364. xscr(fnam,xnam,stext,sflag,stype,extent,opts)
  365. char *fnam;      /* input file name */
  366. char *xnam;      /* output dir or file */
  367. char *stext;     /* search text */
  368. int  *sflag;     /* skip flag 0 = include, 1 = omit default 1 */
  369. int  *stype;     /* search type 0=File, 1=Dir */
  370. char *extent;    /* file extents to include/omit */
  371. char *opts;
  372. {
  373.    char dir[20];
  374.    char file[20];
  375.    static char text[80]  = "   ";
  376.    char skipcom[5];         /* skip com files Omit Include  */
  377.    char dirsrch[5];         /* search directory File Directory */
  378.    char ok[5];              /* items ok */
  379.    int  item,i;
  380.    static char extents[80] = "exe com";    /* extents to skip/include */
  381.    static char options[80] = "u";          /* ignore uppercase */
  382.    char work[80];            /* work area */
  383.  
  384.    dirsrch[0] = 'F';      /* default is file */
  385.    skipcom[0] = 'O';      /* default is omit */
  386.    clrscr();
  387.    cursor(2,10);
  388.    writestr("XDIR - Text Search Aide ");
  389.    sepname(fnam,dir,file);   /* separate name into path and file */
  390.    cursor(5,10);
  391.    writestr("Directory   [                          ]");
  392.    cursor(5,23);
  393.    writestr(dir);
  394.    cursor(7,10);
  395.    writestr("File        [                          ]");
  396.    cursor(7,23);
  397.    writestr(file);
  398.    cursor(9,10);
  399.    writestr("Search text [                                 ]");
  400.    cursor(9,23);
  401.    writestr(text);
  402.    cursor(11,10);
  403.    writestr("File extents[                                 ]");
  404.    cursor(11,23);
  405.    writestr(extents);
  406.    cursor(13,10);
  407.    writestr("Options     [                                 ]");
  408.    cursor(13,23);
  409.    writestr(options);
  410.    cursor(15,10);
  411.    writestr("Include/omit I/O    [O]");
  412.    cursor(17,10);
  413.    writestr("File/Directory  D/F [F]");
  414.    cursor(19,10);
  415.    writestr("Above items OK? Y/N [N]");
  416.    cursor(20,10);
  417.    writestr("Options: Arrow keys, PgUp, PgDn, Home, End, Esc, F1 = Help");
  418.  
  419.    ok[0] = 'N';           /* initial value is no */
  420.    item = 2;
  421.    while (1)
  422.    {
  423.        switch (item)
  424.        {
  425.        case 0:   /* directory selection */
  426.          i=getitem(&item,5,23,dir,25);
  427.          break;
  428.  
  429.        case 1:   /* file selection */
  430.          i=getitem(&item,7,23,file,15);
  431.          break;
  432.  
  433.        case 2:   /* search text */
  434.          i=getitem(&item,9,23,text,33);
  435.          break;
  436.  
  437.        case 3:  /* file extents */
  438.          i = getitem(&item,11,23,extents,33);
  439.          break;
  440.  
  441.        case 4:  /* search options */
  442.          i = getitem(&item,13,23,options,33);
  443.          break;
  444.  
  445.        case 5:  /* include/omit */
  446.          i=getitem(&item,15,31,skipcom,1);
  447.          break;
  448.  
  449.        case 6: /* dirsrch */
  450.          i=getitem(&item,17,31,dirsrch,1);
  451.          break;
  452.  
  453.        case 7:   /* OK  */
  454.          i=getitem(&item,19,31,ok,1);
  455.          break;
  456.        }        /* end switch */
  457.  
  458.        if (ok[0] == 'Y') break;
  459.        if (i == -1) return(-1);  /* escape key was pressed */
  460.      }          /* end while */
  461.  
  462.        if (dirsrch[0] == 'F')
  463.           {
  464.           *stype = 0;
  465.           strcpy(work,dir);      /* build up a fully qualified name */
  466.           strcat(work,"\\");
  467.           strcat(work,file);
  468.           strcpy(xnam,work);
  469.           }
  470.        else
  471.           {
  472.           *stype = 1;
  473.           strcpy(xnam,dir);
  474.           }
  475.  
  476.        if (skipcom[0] == 'O')
  477.           *sflag = 1;
  478.           else *sflag = 0;
  479.  
  480.        strcpy(stext,text);
  481.        strcpy(extent,extents);
  482.        strcpy(opts,options);
  483.        return (0);
  484. }               /* end function */
  485.  
  486.  
  487. /*
  488.    getitem
  489.    get an item
  490.  
  491. */
  492. #define LASTITEM 7
  493. getitem(item,row,col,text,len)
  494. int *item;
  495. int row, col;
  496. char *text;
  497. int  len;         /* display length */
  498. {
  499.      int thisitem;
  500.      char temp[80];
  501.      int  c;
  502.  
  503.      thisitem = *item;     /* get contents */
  504.  
  505.          cursor(row,col);
  506.          c = getch();
  507.          if (c == 0)
  508.             {
  509.             c = getch();
  510.             if (c==80)      ++thisitem;    /* up arrow */
  511.             else if (c==72) --thisitem;    /* down arrow */
  512.             else if (c==71) thisitem = 0;  /* Home */
  513.             else if (c==73) thisitem = 0;  /* PgUp */
  514.             else if (c==79) thisitem = LASTITEM;  /* End */
  515.             else if (c==81) thisitem = LASTITEM;  /* PgDn */
  516.             else if (c==59) ;              /* F1 - Help */
  517.             else putchar(7);
  518.             }
  519.          else if (c==13) ++thisitem;
  520.          else if (c==27) return(-1);
  521.          else if (thisitem < 5)
  522.             {
  523.             temp[0] = c;
  524.             cline(row,col,len);     /* clear the line to spaces */
  525.             cursor(row,col);        /* reset the cursor */
  526.             putchar(c);
  527.             gets(temp+1);
  528.             strcpy(text,temp);
  529.             ++thisitem;
  530.             }
  531.          else
  532.             {
  533.             c = toupper(c);
  534.             switch (thisitem)
  535.             {
  536.             case 5:
  537.               if ((c == 'I') || (c == 'O'))
  538.                  {text[0] = c;putchar(c);++thisitem;}
  539.                  else putchar(7);
  540.               break;
  541.             case 6:
  542.               if ((c == 'F') || (c == 'D'))
  543.                   {text[0] = c;putchar(c);++thisitem;}
  544.                  else putchar(7);
  545.               break;
  546.             case 7:
  547.               if ((c == 'Y') || (c == 'N'))
  548.                     {text[0] = c;putchar(c);++thisitem;}
  549.                  else putchar(7);
  550.               break;
  551.             }
  552.             }
  553.  
  554.      if (thisitem < 0) thisitem = LASTITEM;
  555.      if (thisitem > LASTITEM) thisitem = 0;
  556.  
  557.      if (c == 59)
  558.         {
  559.         int i;
  560.         cursor(22,10);
  561.         for (i=0;i<50;i++) putchar(' ');
  562.         cursor(22,10);
  563.  
  564.         switch (thisitem)
  565.         {
  566.         case 0:
  567.            writestr("Enter name of directory such as \\123 ");
  568.            break;
  569.         case 1:
  570.            writestr("For single file search enter DOS name ");
  571.            break;
  572.          case 2:
  573.            writestr("Enter text to search ");
  574.            break;
  575.          case 3:
  576.            writestr("File extents to skip/include (e.g.EXE and .COM) ");
  577.            break;
  578.          case 4:
  579.            writestr("Search options [u]pper case [w]hole words ");
  580.            break;
  581.          case 5:
  582.            writestr("Enter [I]nclude or [O]mit ");
  583.            break;
  584.          case 6:
  585.            writestr("Search [F]ile or [D]irectory ");
  586.            break;
  587.          case 7:
  588.            writestr("If all info is ok, [Y]es, else change ");
  589.            break;
  590.          } /* end case */
  591.  
  592.        }   /* end if */
  593.  
  594.        *item = thisitem;
  595.        return (0);
  596.  
  597. }         /* end function */
  598.  
  599. /*
  600.   sepname
  601.   separate a path + file name into their parts
  602.  
  603. */
  604. void sepname(all,path,file)
  605. char *all, *path, *file;
  606. {
  607.      int  i,j,k,l;
  608.      char temp[80];
  609.  
  610.      i = strlen(all);
  611.  
  612.      for (j=i,k=0;j>=0;j--)
  613.      {
  614.      if (all[j] == '\\') break;
  615.      ++k;
  616.      }
  617.  
  618.      /* k is the length of the file name */
  619.  
  620.      --k;
  621.      strcpy(temp,all);
  622.      l = i - 1 - k;       /* length of path */
  623.      temp[l] = 0;
  624.      strcpy(path,temp);
  625.      strcpy(file,temp+l+1);
  626.  
  627. }
  628.  
  629.  
  630. /*
  631.    cline
  632.    clear a line
  633.  
  634. */
  635. void cline(row,col,len)
  636. int  row,col,len;
  637. {
  638.  
  639.      cursor(row,col);
  640.  
  641.      while (len--) putchar(' ');
  642.  
  643. }
  644. /*
  645.    sdir.c
  646.    process the DOS directories
  647.  
  648. */
  649.  
  650. int  sdir(buff,filename,action,ext,type)
  651. char *buff;         /* directory name */
  652. char *filename;     /* output filename */
  653. int  action;        /* 0 = read , 1=open, 2=close */
  654. char ext[10][80];   /* file extension to search */
  655. int  type;          /* 0 = include, 1 = omit */
  656. {
  657.    static DIR *dir;
  658.    struct direct *dir_entry;
  659.    char   *calloc(int count, int size);
  660.    static char  workfnam[80];
  661.    static char  fileext[14];
  662.    int    i,j,k;
  663.  
  664.    if (action == 1)           /* open the file, setup extension */
  665.    {
  666.    clear(workfnam,80,0);
  667.    strcpy(workfnam,buff);
  668.    strcat(workfnam,"\\*.*");
  669.  
  670.    dir = opendir(workfnam);     /* open directory */
  671.    setdirat(dir,0x3f);          /* search all */
  672.    for (i=0;i<10;i++)
  673.        for (j=0;j<3;j++) ext[i][j] = toupper(ext[i][j]);
  674.    return (1);
  675.    }
  676.  
  677.    /************ sequential directory search **********************/
  678.  
  679.    if (action == 0)
  680.    {
  681.       while ((dir_entry = readdir(dir)) != NULL)
  682.       {
  683.       if (dir_entry->d_attrib & 0x18) continue;  /* skip label and dir */
  684.  
  685.       for (j=k=0;j<10;j++)
  686.       {
  687.       i = cmpext(dir_entry->d_name,ext[j]);     /* file type validation */
  688.       if ((i == 0) && (type == 0))
  689.          {
  690.          strcpy(filename,buff);
  691.          strcat(filename,"\\");
  692.          strcat(filename,dir_entry->d_name);
  693.          return (1);
  694.          }
  695.  
  696.        if ((i == 0) && (type == 1))  ++k;  /* count matches */
  697.       }       /* end for */
  698.  
  699.       if ((type == 1) && (k == 0))
  700.          {
  701.          strcpy(filename,buff);
  702.          strcat(filename,"\\");
  703.          strcat(filename,dir_entry->d_name);
  704.          return (1);
  705.          }
  706.  
  707.    }  /* end while */
  708.  
  709.          closedir(dir);
  710.          return(0);
  711.  
  712.    }  /* end if action == 0 */
  713.  
  714. }
  715.  
  716. /*
  717.   cmpext
  718.   compare file extents
  719.  
  720. */
  721. cmpext(fnam,ext)
  722. char *fnam, *ext;
  723. {
  724.      int i,j;
  725.      char temp[10];
  726.      char work[30];
  727.  
  728.      strcpy(work,fnam);
  729.      i = strlen(fnam);
  730.      for (j=i;j>=0;j--) if(fnam[j] == '.') break;
  731.      ++j;
  732.  
  733.      strcpy(temp,work+j);     /* setup file extension for compare */
  734.      i = strcmp(temp,ext);    /* compare */
  735.      return i;                /* result of compare */
  736. }
  737.  
  738.  
  739. /*
  740.   xcomp
  741.   comparison routine
  742.   for use within scan routine in xdir
  743.  
  744. */
  745. #define NULL 0
  746.  
  747. xcomp(str1,match,options,len)
  748. char *str1;           /* null terminated string */
  749. char *match;          /* string to match */
  750. char *options;        /* options for match */
  751. int  len;             /* length of buffer */
  752. {
  753.      char *cp;
  754.      int  fnd,j;
  755.  
  756.      cp =str1;        /* initialize to first string */
  757.      fnd = 1;         /* indicate no find */
  758.      j = len;
  759.      j += 2;
  760.  
  761.      while (1)  /* search the buffer */
  762.      {
  763.      fnd = xcmp(cp,match,options,j);
  764.      if (fnd == 0) break;
  765.      ++cp;
  766.      --j;
  767.      if (j <= 0) break;
  768.      }
  769.  
  770.      return (fnd);
  771. }
  772.  
  773. /*
  774.    xcmp
  775.    compare two strings, various options
  776.  
  777. */
  778. xcmp(str1,match,options,max)
  779. char *str1;
  780. char *match;          /* string to match */
  781. char *options;
  782. int  max;             /* maximum chars to search */
  783. {
  784.      char *cp, *cps, *cpm;
  785.      char cs,cm,c;
  786.      int  uflag;
  787.      int  wflag;
  788.      int  state;
  789.  
  790.      cps = str1;
  791.      cpm = match;
  792.      uflag = wflag = 0;
  793.      cp = options;
  794.  
  795.      while (c= toupper(*cp++))   /* initialize options */
  796.      {
  797.      if (c == 'U') uflag = 1;
  798.      else
  799.      if (c == 'W') wflag = 1;
  800.      }
  801.  
  802.      state = 0;
  803.  
  804.      while (1)
  805.      {
  806.      switch (state)
  807.      {
  808.      case 0:            /* initial state */
  809.           cs = *cps++;  /* get a character from input stream */
  810.           if (uflag) cs = toupper(cs);
  811.           --max;
  812.           if (max <= 0) return (-1);
  813.           cm = *cpm++;  /* get a match character */
  814.           if (uflag) cm = toupper(cm);
  815.           if (cm == 0)  return (-1);
  816.              else state = 1;
  817.           break;
  818.  
  819.      case 1:  /* test cm is '?'  */
  820.           if (cm == '?') state = 3;
  821.              else state = 2;
  822.           break;
  823.  
  824.      case 2:  /* cm not '?' so test equal */
  825.           if (cm == '*') state = 10;
  826.           else if (cs != cm)  return (-1);
  827.             else state = 3;
  828.           break;
  829.  
  830.      case 3:  /* get another set of comparison characters */
  831.           cs = *cps++;
  832.           if (uflag) cs = toupper(cs);
  833.           --max;
  834.           if (max <= 0) return (-1);
  835.           cm = *cpm++;
  836.           if (uflag) cm = toupper(cm);
  837.           if (cm == 0)                   /* end of match string */
  838.              {
  839.              cs = toupper(cs);
  840.              if ((wflag) && (cs>='A') && (cs <= 'Z'))   return (-1);
  841.              else return 0;                /* a match */
  842.              }
  843.           state = 1;
  844.           break;
  845.  
  846.      case 10:  /* cm was '*'  */
  847.           cm = *cpm++;       /* get terminating character */
  848.           if (cm == 0) return 0;      /* no term, it matches */
  849.           if (uflag) cm = toupper(cm);
  850.           state = 11;
  851.           break;
  852.  
  853.      case 11:                /* loop searching for term char */
  854.           cs = *cps++;       /* next input character */
  855.           if (uflag) cs = toupper(cs);
  856.           --max;
  857.           if (cs <= 0) return (-1);
  858.           if (cs == cm)      /* terminator reached */
  859.              state = 3;      /* get another set of characters */
  860.           break;
  861.  
  862.           }         /* end switch */
  863.  
  864.  
  865.      }              /* end while */
  866.  
  867.  
  868. }
  869.  
  870.  
  871.  
  872.